package logger

import (
	"fmt"
	"io"
	"log"
	"os"
	"strings"
)

// 日志级别
const (
	DEBUG = iota
	INFO
	WARN
	ERROR
	FATAL
)

var (
	// 日志级别名称
	levelNames = map[int]string{
		DEBUG: "DEBUG",
		INFO:  "INFO",
		WARN:  "WARN",
		ERROR: "ERROR",
		FATAL: "FATAL",
	}

	// 日志级别
	consoleLogLevel = INFO
	fileLogLevel    = INFO

	// 日志记录器
	stdLogger  *log.Logger
	fileLogger *log.Logger

	// 日志文件
	logFile *os.File
)

// 初始化日志系统
func Init(level, consoleLevel, fileLevel, filePath string) error {
	// 设置日志级别
	SetLevel(level)
	SetConsoleLevel(consoleLevel)
	SetFileLevel(fileLevel)

	// 初始化控制台日志
	stdLogger = log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds)

	// 如果指定了日志文件，则初始化文件日志
	if filePath != "" {
		var err error
		logFile, err = os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
		if err != nil {
			return fmt.Errorf("无法打开日志文件: %v", err)
		}

		fileLogger = log.New(logFile, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds)

		// 如果需要同时输出到控制台和文件
		if level == "both" {
			multiWriter := io.MultiWriter(os.Stdout, logFile)
			stdLogger.SetOutput(multiWriter)
			fileLogger = stdLogger
		}
	}

	return nil
}

// 关闭日志文件
func Close() {
	if logFile != nil {
		logFile.Close()
	}
}

// 解析日志级别
func parseLevel(level string) int {
	switch strings.ToUpper(level) {
	case "DEBUG":
		return DEBUG
	case "INFO":
		return INFO
	case "WARN":
		return WARN
	case "ERROR":
		return ERROR
	case "FATAL":
		return FATAL
	default:
		return INFO
	}
}

// 设置全局日志级别
func SetLevel(level string) {
	lvl := parseLevel(level)
	consoleLogLevel = lvl
	fileLogLevel = lvl
}

// 设置控制台日志级别
func SetConsoleLevel(level string) {
	consoleLogLevel = parseLevel(level)
}

// 设置文件日志级别
func SetFileLevel(level string) {
	fileLogLevel = parseLevel(level)
}

// 记录日志的通用函数
func log2(level int, prefix, format string, v ...interface{}) {
	message := format
	if len(v) > 0 {
		message = fmt.Sprintf(format, v...)
	}

	// 使用 levelNames 变量
	levelName := levelNames[level]
	prefix = fmt.Sprintf("[%s] ", levelName)

	// 输出到控制台
	if level >= consoleLogLevel && stdLogger != nil {
		stdLogger.SetPrefix(prefix)
		stdLogger.Output(3, message)
	}

	// 输出到文件
	if level >= fileLogLevel && fileLogger != nil && fileLogger != stdLogger {
		fileLogger.SetPrefix(prefix)
		fileLogger.Output(3, message)
	}
}

// Debug 记录调试级别日志
func Debug(format string, v ...interface{}) {
	log2(DEBUG, "[DEBUG] ", format, v...)
}

// Info 记录信息级别日志
func Info(format string, v ...interface{}) {
	log2(INFO, "[INFO] ", format, v...)
}

// Warn 记录警告级别日志
func Warn(format string, v ...interface{}) {
	log2(WARN, "[WARN] ", format, v...)
}

// Error 记录错误级别日志
func Error(format string, v ...interface{}) {
	log2(ERROR, "[ERROR] ", format, v...)
}

// Fatal 记录致命错误并退出
func Fatal(format string, v ...interface{}) {
	log2(FATAL, "[FATAL] ", format, v...)
	os.Exit(1)
}
